import { computed, ref, watch } from 'vue';
import { useRoute } from 'vue-router';
import { useContext } from '@sa/hooks';
import { useRouteStore } from '@/store/modules/route';

export const { setupStore: setupMixMenuContext, useStore: useMixMenuContext } = useContext('mix-menu', useMixMenu);
/** useMixMenu 是一个自定义钩子函数，用于管理和提供关于混合菜单（Mix Menu）的上下文信息。 它返回一个包含所有菜单、一级菜单、子菜单以及当前激活的菜单状态的对象。 */
function useMixMenu() {
  // 获取当前路由信息
  const route = useRoute();
  // 获取路由状态管理实例
  const routeStore = useRouteStore();
  // 从 useMenu 钩子中获取选中的菜单键
  const { selectedKey } = useMenu();

  // 创建一个名为 activeFirstLevelMenuKey 的响应式变量，用于存储当前激活的一级菜单键
  const activeFirstLevelMenuKey = ref('');

  /**
   * 设置当前激活的一级菜单键。
   *
   * @param key - 要设置的一级菜单键。
   */
  function setActiveFirstLevelMenuKey(key: string) {
    activeFirstLevelMenuKey.value = key;
  }

  /** 获取当前激活的一级菜单键。 根据选中的菜单键获取并设置激活的一级菜单键。 */
  function getActiveFirstLevelMenuKey() {
    // 从选中的菜单键中提取一级路由名称
    const [firstLevelRouteName] = selectedKey.value.split('_');
    // 设置激活的一级菜单键
    setActiveFirstLevelMenuKey(firstLevelRouteName);
  }

  /** 计算属性，返回所有菜单。 */
  const allMenus = computed<App.Global.Menu[]>(() => routeStore.menus);

  /** 计算属性，返回一级菜单。 从所有菜单中提取一级菜单，忽略子菜单。 */
  const firstLevelMenus = computed<App.Global.Menu[]>(() =>
    routeStore.menus.map(menu => {
      // 忽略子菜单
      const { children: _, ...rest } = menu;
      // 返回一级菜单
      return rest;
    })
  );

  /** 计算属性，返回当前激活的一级菜单的子菜单。 根据激活的一级菜单键查找对应的子菜单。 */
  const childLevelMenus = computed<App.Global.Menu[]>(
    () => routeStore.menus.find(menu => menu.key === activeFirstLevelMenuKey.value)?.children || []
  );

  /** 计算属性，判断当前激活的一级菜单是否有子菜单。 */
  const isActiveFirstLevelMenuHasChildren = computed(() => {
    if (!activeFirstLevelMenuKey.value) {
      return false;
    }

    // 在所有菜单中查找当前激活的一级菜单
    const findItem = allMenus.value.find(item => item.key === activeFirstLevelMenuKey.value);

    // 如果找到了当前激活的一级菜单，并且它有子菜单，则返回 true，否则返回 false
    return Boolean(findItem?.children?.length);
  });

  /** 监听路由变化，当路由名称发生变化时，更新激活的一级菜单键。 */
  watch(
    () => route.name,
    () => {
      getActiveFirstLevelMenuKey();
    },
    { immediate: true }
  );

  // 返回包含所有菜单、一级菜单、子菜单、激活状态、激活的一级菜单键以及设置和获取激活的一级菜单键的方法的对象
  return {
    allMenus,
    firstLevelMenus,
    childLevelMenus,
    isActiveFirstLevelMenuHasChildren,
    activeFirstLevelMenuKey,
    setActiveFirstLevelMenuKey,
    getActiveFirstLevelMenuKey
  };
}

/** useMenu 是一个自定义钩子函数，用于获取当前选中的菜单键。 它返回一个包含选中菜单键的对象。 */
export function useMenu() {
  // 获取当前路由信息
  const route = useRoute();

  /** 计算属性，返回当前选中的菜单键。 根据路由元信息中的 hideInMenu 和 activeMenu 来确定选中的菜单键。 */
  const selectedKey = computed(() => {
    // 从路由元信息中获取 hideInMenu 和 activeMenu
    const { hideInMenu, activeMenu } = route.meta;
    // 获取当前路由的名称
    const name = route.name as string;

    // 如果 hideInMenu 为 true，则使用 activeMenu 作为选中的菜单键，否则使用当前路由的名称
    const routeName = (hideInMenu ? activeMenu : name) || name;

    return routeName;
  });

  // 返回包含选中菜单键的对象
  return {
    selectedKey
  };
}
